﻿using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using POC.Logger;
using POC.Loggers.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace POC.Loggers.Storage
{
   public class TableStorageRespository : ICloudStorageRespository
    {
        AzureAccount _account;
        CloudTable table;
        string _tableName;

        private TableStorageRespository(AzureAccount account)
        {
            _account = account;
        }
        public TableStorageRespository(AzureAccount account, string partitionName)
        {
            _account = account;
            _tableName = Regex.Replace(partitionName, "[^a-zA-Z0-9]+", "", RegexOptions.Compiled);
        }
        public void InitializeRepository()
        {
            if (table == null)
            {
                CloudTableClient tableClient = _account.CloudAccount.CreateCloudTableClient();
                table = tableClient.GetTableReference(_tableName);
            }
            table.CreateIfNotExists();
        }
        public Task PutEntry(LogEntry entry, bool lazyExecute)
        {
            Task<TableResult> task = null;
            if (table == null)
            {
                InitializeRepository();
            }
            TableOperation insertOperation = TableOperation.Insert(entry);
            if (lazyExecute)
            {
                task = Task<TableResult>.Factory.FromAsync(table.BeginExecute, table.EndExecute, insertOperation, null);
            }
            else
            {
                table.Execute(insertOperation);   
            }
            return task;
        }
        public List<LogEntry> GetAllEntries(string[] columnsName = null)
        {
            List<LogEntry> entries = new List<LogEntry>();
            if (table == null)
            {
                InitializeRepository();
            }
            string part = DateTime.Now.ToString("MM_yyyy");
            // Create the table query.
            TableQuery<LogEntry> rangeQuery = new TableQuery<LogEntry>().Where(
                TableQuery.CombineFilters(
                    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, part),
                    TableOperators.And,
                    TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.NotEqual, "")));
            
            if (columnsName != null)
            {
                rangeQuery.SelectColumns = columnsName;
            }
            var rows = table.ExecuteQuery(rangeQuery);
            entries = rows.ToList();
            return entries;
        }

        public List<LogEntry> GetEntries(string query="", string[] columnsName=null, int pageIndex = 1, int pageSize=100)
        {
            List<LogEntry> entries = new List<LogEntry>();
            if (table == null)
            {
                InitializeRepository();
            }
            string part = DateTime.Now.ToString("MM_yyyy");
            // Create the table query.
            TableQuery<LogEntry> rangeQuery = new TableQuery<LogEntry>().Where(
                TableQuery.CombineFilters(
                    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, part),
                    TableOperators.And,
                    TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.NotEqual, "")));
            if (!string.IsNullOrEmpty(query))
            {
                rangeQuery.FilterString = query;
            }
            if (columnsName != null)
            {
                rangeQuery.SelectColumns = columnsName;
            }
            rangeQuery.TakeCount = pageSize;
            var rows = table.ExecuteQuery(rangeQuery);
            entries = rows.ToList();
            return entries;
        }
        public IEnumerable<LogEntry> Get(string tableName, string partitionKey, IEnumerable<string> rowKeys)
        {
            CloudTableClient tableClient = _account.CloudAccount.CreateCloudTableClient();
            var context = tableClient.GetTableServiceContext();
            List<LogEntry> entries = new List<LogEntry>();
            return entries;
        }
    }
}
